import {ElMessage} from "element-plus";

// export function generateRandomNumbers(form) {
//     let {count, targetMean, targetStdDev, maxValue} = form
//     // targetMean,plusNum,minNum,maxValue
//     // const targetMean = 52.08;
//     // const targetStdDev = 10.76;
//     // const count = 41;
//     // const maxValue = 144;
//     let numbers = [];
//     let sum = 0;
//
//     // 生成符合正态分布的随机数
//     for (let i = 0; i < count; i++) {
//         let num;
//         do {
//             num = Math.round(normalRandom(targetMean, targetStdDev));
//         } while (num < 0 || num > maxValue);
//         numbers.push(num);
//         sum += num;
//     }
//
//     // 调整总和以精确匹配目标均值
//     const targetSum = Math.round(targetMean * count);
//     const diff = targetSum - sum;
//     if (diff !== 0) {
//         adjustNumbers(numbers, diff, maxValue);
//     }
//
//     // 打乱顺序
//     return shuffleArray(numbers);
// }
//
// function normalRandom(mean, stdDev) {
//     let u = 0, v = 0;
//     while (u === 0) u = Math.random();
//     while (v === 0) v = Math.random();
//     return mean + stdDev * Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
// }
//
// function adjustNumbers(arr, diff, maxValue) {
//     const step = diff > 0 ? 1 : -1;
//     let remaining = Math.abs(diff);
//
//     while (remaining > 0) {
//         const index = Math.floor(Math.random() * arr.length);
//         if ((step === 1 && arr[index] < maxValue) ||
//             (step === -1 && arr[index] > 0)) {
//             arr[index] += step;
//             remaining--;
//         }
//     }
// }
//
// function shuffleArray(array) {
//     for (let i = array.length - 1; i > 0; i--) {
//         const j = Math.floor(Math.random() * (i + 1));
//         [array[i], array[j]] = [array[j], array[i]];
//     }
//     return array;
// }

// // 生成并输出结果
// const result = generateRandomNumbers();
// console.log(result.join('\n'));

// export function generateRandomNumbers(form) {
//     let {count, targetMean, targetStdDev, maxValue, decimalPlaces = 0} = form
//
//     // const targetMean = 52.08;
//     // const targetStdDev = 10.76;
//     // const count = 41;
//     let numbers = [];
//     let sum = 0;
//
//     // 生成符合正态分布的随机数
//     for (let i = 0; i < count; i++) {
//         let num;
//         do {
//             num = normalRandom(targetMean, targetStdDev);
//             num = parseFloat(num.toFixed(decimalPlaces));
//         } while (num < 0 || (maxValue && num > maxValue));
//         numbers.push(num);
//         sum += num;
//     }
//
//     // 调整总和以精确匹配目标均值
//     const targetSum = parseFloat((targetMean * count).toFixed(decimalPlaces));
//     const diff = parseFloat((targetSum - sum).toFixed(decimalPlaces));
//     if (diff !== 0) {
//         adjustNumbers(numbers, diff, maxValue, decimalPlaces);
//     }
// // .join('\n');
//     // 打乱顺序并格式化为每行一个数字
//     return shuffleArray(numbers)
// }
//
// function normalRandom(mean, stdDev) {
//     let u = 0, v = 0;
//     while(u === 0) u = Math.random();
//     while(v === 0) v = Math.random();
//     return mean + stdDev * Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
// }
//
// function adjustNumbers(arr, diff, maxValue, decimalPlaces) {
//     const step = diff > 0 ? 1 : -1;
//     let remaining = Math.abs(diff);
//     const adjustment = parseFloat(Math.pow(0.1, decimalPlaces).toFixed(decimalPlaces));
//
//     while (remaining > 0) {
//         const index = Math.floor(Math.random() * arr.length);
//         const newValue = parseFloat((arr[index] + step * adjustment).toFixed(decimalPlaces));
//
//         if ((step === 1 && (!maxValue || newValue <= maxValue)) ||
//             (step === -1 && newValue >= 0)) {
//             remaining = parseFloat((remaining - adjustment).toFixed(decimalPlaces));
//             arr[index] = newValue;
//         }
//     }
// }
//
// function shuffleArray(array) {
//     for (let i = array.length - 1; i > 0; i--) {
//         const j = Math.floor(Math.random() * (i + 1));
//         [array[i], array[j]] = [array[j], array[i]];
//     }
//     return array;
// }
export function generateRandomNumbers(form) {
    const { count, targetMean, targetStdDev, maxValue, decimalPlaces = 0 } = form;
    const round = (num) => Math.round(num * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
    const numbers = [];

    // ------------------------------
    // 步骤1：生成初始正态分布随机数（带范围限制）
    // ------------------------------
    const generateInitial = () => {
        const temp = [];
        for (let i = 0; i < count; i++) {
            let num;
            do {
                num = normalRandom(targetMean, targetStdDev); // 正态分布生成
                num = round(num); // 按小数位取整
            } while ((num < 0) || (maxValue !== undefined && num > maxValue)); // 范围校验
            temp.push(num);
        }
        return temp;
    };
    let currentNumbers = generateInitial();

    // ------------------------------
    // 步骤2：定义核心调整逻辑（优先均值，再次标准差）
    // ------------------------------
    const adjustOptimize = () => {
        const maxIterations = 2000; // 增加迭代次数确保收敛
        let iteration = 0;
        const stepBase = Math.pow(10, -decimalPlaces); // 动态步长（支持小数位）

        while (iteration++ < maxIterations) {
            const currentSum = currentNumbers.reduce((a, b) => a + b, 0);
            const currentMean = currentSum / count;
            const currentStdDev = calculateSampleStdDev(currentNumbers, currentMean);

            // === 优先级1：强制保证平均值 ≥ targetMean（无限接近） ===
            if (currentMean < targetMean) {
                // 计算需要补充的总差值（至少需要达到 targetMean * count）
                const requiredSum = Math.max(targetMean * count, currentSum);
                const sumDiff = requiredSum - currentSum;

                // 随机选择数值增大（步长=1或小数位步长）
                const index = Math.floor(Math.random() * count);
                const newVal = Math.min(
                    maxValue || Infinity,
                    round(currentNumbers[index] + stepBase * (decimalPlaces === 0 ? 1 : 1)) // 统一步长避免过度波动
                );

                if (newVal > currentNumbers[index]) {
                    currentNumbers[index] = newVal;
                    continue; // 优先处理均值，本轮跳过标准差调整
                }
            }

            // === 优先级2：保证标准差 ≤ targetStdDev（无限接近） ===
            if (currentStdDev > targetStdDev) {
                // 计算每个数与均值的偏离程度（绝对值）
                const deviations = currentNumbers.map(num => Math.abs(num - currentMean));
                // 选择偏离最大的数（调整效率最高）
                const maxDevIndex = deviations.indexOf(Math.max(...deviations));
                const currentNum = currentNumbers[maxDevIndex];
                const deviation = currentNum - currentMean;

                // 向均值方向调整（偏离越大，调整步长越大）
                const adjustStep = (deviation / currentMean) * stepBase * 2; // 动态步长（最大2倍基础步长）
                const newVal = round(currentNum - (deviation > 0 ? adjustStep : -adjustStep));

                // 校验范围并更新
                if ((deviation > 0 && newVal >= 0) || (deviation < 0 && (maxValue === undefined || newVal <= maxValue))) {
                    currentNumbers[maxDevIndex] = newVal;
                }
                continue;
            }

            // 两个条件都满足时退出循环
            return true;
        }
        return false; // 理论上不会触发（maxIterations足够大）
    };

    // ------------------------------
    // 步骤3：执行调整并验证结果
    // ------------------------------
    adjustOptimize(); // 执行核心调整

    // ------------------------------
    // 步骤4：最终校验（防止极端情况）
    // ------------------------------
    let finalMean = currentNumbers.reduce((a, b) => a + b, 0) / count;
    if (finalMean < targetMean) {
        // 极端情况：均值仍不足，强制补足（仅调整1次）
        const requiredSum = Math.ceil(targetMean * count * 100) / 100; // 保留2位小数避免浮点误差
        const currentSum = currentNumbers.reduce((a, b) => a + b, 0);
        const diff = requiredSum - currentSum;
        if (diff > 0) {
            for (let i = 0; i < count && diff > 0; i++) {
                currentNumbers[i] = Math.min(maxValue || Infinity, currentNumbers[i] + 1);
                diff--;
            }
        }
    }

    // ------------------------------
    // 步骤5：打乱顺序并格式化输出
    // ------------------------------
    return shuffleArray(currentNumbers).map(n => n.toFixed(decimalPlaces));
}

// ------------------------------
// 工具函数（优化版）
// ------------------------------
function normalRandom(mean, stdDev) {
    let u = 0, v = 0;
    while (u <= 0) u = Math.random(); // 避免0值（Box-Muller变换要求u∈(0,1)）
    while (v <= 0) v = Math.random();
    return mean + stdDev * Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
}

function calculateSampleStdDev(values, mean) {
    if (values.length < 2) return 0;
    const squaredDiffs = values.map(v => Math.pow(v - mean, 2));
    const variance = squaredDiffs.reduce((a, b) => a + b, 0) / (values.length - 1); // 样本方差（分母n-1）
    return Math.sqrt(variance);
}

function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
}

export function generateRandomCancerTypes(cancers) {
    // Fisher-Yates洗牌算法实现随机排序
    for (let i = cancers.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [cancers[i], cancers[j]] = [cancers[j], cancers[i]];
    }

    // 转换为每行一个元素的文本格式
    return cancers
}


export function copyValue(value) {
    try {
        // 创建一个临时的输入框来存储文本
        const input = document.createElement('textarea');
        input.value = value;
        // 将输入框添加到页面，但不显示
        document.body.appendChild(input);
        input.select(); // 选择输入框的内容
        // 执行复制操作
        const isSuccessful = document.execCommand('copy');
        // 清除临时输入框
        document.body.removeChild(input);
        ElMessage({
            message: `复制成功`,
            duration: 2000,
            type: 'success',
        })
    } catch (err) {
    }
}

// 输出结果
// console.log(generateRandomCancerTypes());